package com.service.business.merchant.controller;

import com.service.business.base.dto.LoginUserSession;
import com.service.business.base.service.ConfigService;
import com.service.business.framework.log.RequestLog;
import com.service.business.member.service.MemberService;
import com.service.business.member.service.MemberStoreService;
import com.service.business.merchant.controller.rep.CreditLineStatementPageRep;
import com.service.business.merchant.controller.rep.MemberCreditLineRep;
import com.service.business.merchant.controller.req.RepaymentReq;
import com.service.business.merchant.service.MerchantCreditLineService;
import com.service.business.merchant.service.MerchantService;
import com.service.business.support.Language;
import com.service.business.support.MemberMerchantLockUtils;
import com.service.business.support.MemberStoreLockUtils;
import com.service.business.support.SessionUtil;
import com.service.business.utils.I18nUtil;
import com.service.core.exception.CommonException;
import com.service.core.rest.BaseController;
import com.service.core.rest.request.PageRequest;
import com.service.core.rest.response.BaseResponse;
import com.service.core.rest.response.OneResponse;
import com.service.core.rest.response.PageResponse;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.model.MemberStore;
import com.service.dao.model.Merchant;
import com.service.dao.model.MerchantCreditLine;
import com.service.dao.model.SysConfig;
import com.service.utility.common.MathUtil;
import org.redisson.RedissonRedLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;


/**
 * 商家信用额度
 *
 * @author xxxx
 * @email xxxx@qq.com
 * @date 2020-04-01 20:13:14
 */
@RestController
@RequestMapping("merchant-credit-line")
public class MerchantCreditLineController extends BaseController {

    @Autowired
    private SessionUtil sessionUtil;
    @Autowired
    private MemberService memberService;
    @Autowired
    private ConfigService configService;
    @Autowired
    private MemberStoreService storeService;
    @Autowired
    private MerchantService merchantService;
    @Autowired
    private MemberStoreLockUtils storeLockUtils;
    @Autowired
    private MerchantCreditLineService merchantCreditLineService;

    @GetMapping("balance")
    @RequestLog("授信额度余额")
    public OneResponse<MemberCreditLineRep> creditLine() {
        return successQueryOneResponse(merchantCreditLineService.merchantCreditLine());
    }

    @RequestLog("授信额度流水")
    @PostMapping("statement-page/{coin}")
    public PageResponse<CreditLineStatementPageRep> pageStatement(@PathVariable("coin") CoinsEnum coins, @RequestBody PageRequest pageRequest) {
        return successQueryPageResponse(merchantCreditLineService.pageStatement(coins, pageRequest));
    }

    @RequestLog("还款接口")
    @PostMapping("repayment")
    public BaseResponse repayment(@RequestBody @Validated RepaymentReq repaymentReq) {
        LoginUserSession session = sessionUtil.getUser();

        memberService.validSafetyPwd(session.getUserId(), repaymentReq.getSafetyPwd());

        Merchant merchant = merchantService.getByMemberId(session.getUserId());
        if (ObjectUtils.isEmpty(merchant)) {
            throw new CommonException("暂未开通商家服务", "merchant_exception_not_service");
        }
        SysConfig config = configService.getConfigByName(ConfigConstants.MERCHANT_CREDIT_LINE_COINS);
        CoinsEnum repaymentCoin = CoinsEnum.valueOf(config.getConfOptions());

        MemberStore memberStore = storeService.getMemberStore(session.getUserId(), repaymentCoin.getName());
        if (MathUtil.isLEZero(memberStore.getNum())) {
            String msg = I18nUtil.getMessage("member_store_exception_by_error", Language.LANG.get(), memberStore.getCoinsName());
            throw new CommonException(msg);
        }

        MerchantCreditLine creditLine = merchantCreditLineService.getCreditLine(merchant.getId(), repaymentCoin);
        BigDecimal repaymentNum = creditLine.getCreditNum().subtract(creditLine.getResidueNum());
        if (MathUtil.isLEZero(repaymentNum)) {
            throw new CommonException("暂无欠款", "merchant_credit_line_not_debt");
        }

        List<String> lockKeyList = MemberStoreLockUtils.buildStoreKey2List(memberStore);
        lockKeyList.add(MemberMerchantLockUtils.buildCreditLineLock(merchant.getId(), repaymentCoin.getName()));
        RedissonRedLock redLock = storeLockUtils.getRedLock(lockKeyList);
        try {
            if (storeLockUtils.redLockTryLock(redLock)) {
                merchantCreditLineService.repayment(creditLine, memberStore, repaymentNum);
            }
        } finally {
            redLock.unlock();
        }

        return successBaseResponse();
    }

}
